using UnityEngine;
using UnityEngine.UI;

namespace MaterialUI
{
	[AddComponentMenu("MaterialUI/Rect Transform Snap", 50)]
	[ExecuteInEditMode]
	[RequireComponent(typeof(RectTransform))]
	public class RectTransformSnap : MonoBehaviour, ILayoutElement, ILayoutSelfController, ILayoutController
	{
		[SerializeField]
		private RectTransform m_RectTransform;

		[SerializeField]
		private RectTransform m_SourceRectTransform;

		[SerializeField]
		private Vector2 m_Padding;

		[SerializeField]
		private Vector2 m_Offset;

		[SerializeField]
		private bool m_ValuesArePercentage;

		[SerializeField]
		private Vector2 m_PaddingPercent = new Vector2(100f, 100f);

		[SerializeField]
		private Vector2 m_OffsetPercent;

		[SerializeField]
		private bool m_SnapEveryFrame = true;

		[SerializeField]
		private bool m_SnapWidth = true;

		[SerializeField]
		private bool m_SnapHeight = true;

		[SerializeField]
		private bool m_SnapPositionX = true;

		[SerializeField]
		private bool m_SnapPositionY = true;

		private Rect m_LastRect;

		private Rect m_LayoutRect;

		private DrivenRectTransformTracker m_Tracker = default(DrivenRectTransformTracker);

		public RectTransform rectTransform
		{
			get
			{
				if (!m_RectTransform)
				{
					m_RectTransform = (base.transform as RectTransform);
				}
				return m_RectTransform;
			}
		}

		public RectTransform sourceRectTransform
		{
			get
			{
				return m_SourceRectTransform;
			}
			set
			{
				m_SourceRectTransform = value;
				SetLayoutDirty();
			}
		}

		public Vector2 padding
		{
			get
			{
				return m_Padding;
			}
			set
			{
				m_Padding = value;
				SetLayoutDirty();
			}
		}

		public Vector2 offset
		{
			get
			{
				return m_Offset;
			}
			set
			{
				m_Offset = value;
				SetLayoutDirty();
			}
		}

		public bool valuesArePercentage
		{
			get
			{
				return m_ValuesArePercentage;
			}
			set
			{
				m_ValuesArePercentage = value;
				SetLayoutDirty();
			}
		}

		public Vector2 paddingPercent
		{
			get
			{
				return m_PaddingPercent;
			}
			set
			{
				m_PaddingPercent = value;
				SetLayoutDirty();
			}
		}

		public Vector2 offsetPercent
		{
			get
			{
				return m_OffsetPercent;
			}
			set
			{
				m_OffsetPercent = value;
				SetLayoutDirty();
			}
		}

		public bool snapEveryFrame
		{
			get
			{
				return m_SnapEveryFrame;
			}
			set
			{
				m_SnapEveryFrame = value;
			}
		}

		public bool snapWidth
		{
			get
			{
				return m_SnapWidth;
			}
			set
			{
				m_SnapWidth = value;
				SetLayoutDirty();
			}
		}

		public bool snapHeight
		{
			get
			{
				return m_SnapHeight;
			}
			set
			{
				m_SnapHeight = value;
				SetLayoutDirty();
			}
		}

		public bool snapPositionX
		{
			get
			{
				return m_SnapPositionX;
			}
			set
			{
				m_SnapPositionX = value;
				SetLayoutDirty();
			}
		}

		public bool snapPositionY
		{
			get
			{
				return m_SnapPositionY;
			}
			set
			{
				m_SnapPositionY = value;
				SetLayoutDirty();
			}
		}

		public float minWidth => -1f;

		public float preferredWidth => m_LayoutRect.width;

		public float flexibleWidth => -1f;

		public float minHeight => -1f;

		public float preferredHeight => m_LayoutRect.height;

		public float flexibleHeight => -1f;

		public int layoutPriority => 0;

		private void Awake()
		{
			SetLayoutDirty();
		}

		private void OnEnable()
		{
			SetLayoutDirty();
		}

		private void OnDisable()
		{
			m_Tracker.Clear();
			SetLayoutDirty();
		}

		private void OnValidate()
		{
			SetLayoutDirty();
		}

		private void LateUpdate()
		{
			if ((bool)m_SourceRectTransform && m_SnapEveryFrame)
			{
				Rect rect = new Rect(m_SourceRectTransform.position, m_SourceRectTransform.GetProperSize());
				if (m_LastRect != rect)
				{
					m_LastRect = rect;
					CalculateLayoutInputHorizontal();
					SetLayoutHorizontal();
					CalculateLayoutInputVertical();
					SetLayoutVertical();
				}
			}
		}

		public void SetLayoutDirty()
		{
			LayoutRebuilder.MarkLayoutForRebuild(rectTransform);
		}

		public void CalculateLayoutInputHorizontal()
		{
			if (!m_SourceRectTransform)
			{
				return;
			}
			if (m_SnapPositionX)
			{
				Vector3 position = m_SourceRectTransform.position;
				float x = position.x;
				Vector2 position2 = m_LayoutRect.position;
				if (m_ValuesArePercentage)
				{
					position2.x = x * m_OffsetPercent.x * 0.01f;
				}
				else
				{
					position2.x = x + m_Offset.x;
				}
				m_LayoutRect.position = position2;
			}
			if (m_SnapWidth)
			{
				Vector2 properSize = m_SourceRectTransform.GetProperSize();
				float x2 = properSize.x;
				Rect layoutRect = m_LayoutRect;
				if (m_ValuesArePercentage)
				{
					layoutRect.width = x2 * m_PaddingPercent.x * 0.01f;
				}
				else
				{
					layoutRect.width = x2 + m_Padding.x;
				}
				m_LayoutRect = layoutRect;
			}
		}

		public void CalculateLayoutInputVertical()
		{
			if (!m_SourceRectTransform)
			{
				return;
			}
			if (m_SnapPositionY)
			{
				Vector3 position = m_SourceRectTransform.position;
				float y = position.y;
				Vector2 position2 = m_LayoutRect.position;
				if (m_ValuesArePercentage)
				{
					position2.y = y * m_OffsetPercent.y * 0.01f;
				}
				else
				{
					position2.y = y + m_Offset.y;
				}
				m_LayoutRect.position = position2;
			}
			if (m_SnapHeight)
			{
				Vector2 properSize = m_SourceRectTransform.GetProperSize();
				float y2 = properSize.y;
				Rect layoutRect = m_LayoutRect;
				if (m_ValuesArePercentage)
				{
					layoutRect.height = y2 * m_PaddingPercent.y * 0.01f;
				}
				else
				{
					layoutRect.height = y2 + m_Padding.y;
				}
				m_LayoutRect = layoutRect;
			}
		}

		public void SetLayoutHorizontal()
		{
			m_Tracker.Clear();
			if ((bool)m_SourceRectTransform)
			{
				if (m_SnapPositionX)
				{
					m_Tracker.Add(this, rectTransform, DrivenTransformProperties.AnchoredPositionX);
					Vector3 position = rectTransform.position;
					Vector2 position2 = m_LayoutRect.position;
					position.x = position2.x;
					rectTransform.position = position;
				}
				if (m_SnapWidth)
				{
					m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaX);
					rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, m_LayoutRect.width);
				}
			}
		}

		public void SetLayoutVertical()
		{
			if ((bool)m_SourceRectTransform)
			{
				if (m_SnapPositionY)
				{
					m_Tracker.Add(this, rectTransform, DrivenTransformProperties.AnchoredPositionY);
					Vector3 position = rectTransform.position;
					Vector2 position2 = m_LayoutRect.position;
					position.y = position2.y;
					rectTransform.position = position;
				}
				if (m_SnapHeight)
				{
					m_Tracker.Add(this, rectTransform, DrivenTransformProperties.SizeDeltaY);
					rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, m_LayoutRect.height);
				}
			}
		}
	}
}
